package mark.tom.hawk;

import android.util.Log;

import java.util.List;

import mark.tom.hawk.template.Logger;
import mark.tom.hawk.template.Serializer;

class HawkSerializer implements Serializer {

    private static final char DELIMITER = '@';
    private static final String INFO_DELIMITER = "#";
    private static final char NEW_VERSION = 'V';

    private final Logger logger;

    HawkSerializer(Logger logger) {
        this.logger = logger;
    }

    @Override
    public <T> String serialize(String cipherText, T originalGivenValue) {
        Util.checkNullOrEmpty("Cipher text", cipherText);
        Util.checkNull("Value", originalGivenValue);

        String keyClassName = "";
        char dataType;
        if (List.class.isAssignableFrom(originalGivenValue.getClass())) {
            List<?> list = (List<?>) originalGivenValue;
            if (!list.isEmpty()) {
                keyClassName = list.get(0).getClass().getName();
            }
            dataType = DataInfo.TYPE_LIST;
        } else {
            dataType = DataInfo.TYPE_OBJECT;
            keyClassName = originalGivenValue.getClass().getName();
        }

        return keyClassName + INFO_DELIMITER +
                "" + INFO_DELIMITER +
                dataType + NEW_VERSION + DELIMITER +
                cipherText;
    }

    @Override
    public DataInfo deserialize(String serializedText) {
        String[] infos = serializedText.split(INFO_DELIMITER);

        char type = infos[2].charAt(0);

        // if it is collection, no need to create the class object
        Class<?> keyClazz = null;
        String firstElement = infos[0];
        if (firstElement != null && firstElement.length() != 0) {
            try {
                keyClazz = Class.forName(firstElement);
            } catch (ClassNotFoundException e) {
                logger.log("HawkSerializer -> " + e.getMessage(), Log.ERROR);
            }
        }

        String cipherText = getCipherText(infos[infos.length - 1]);
        return new DataInfo(type, cipherText, keyClazz);
    }

    private String getCipherText(String serializedText) {
        int index = serializedText.indexOf(DELIMITER);
        if (index == -1) {
            throw new IllegalArgumentException("Text should contain delimiter");
        }
        return serializedText.substring(index + 1);
    }

}
